<template>
  <div class="tmap-address-display">
    <!-- 地址展示 -->
    <el-tooltip
      :content="modelValue?.address"
      :disabled="!showTooltip"
      placement="top"
    >
      <el-text class="address-text" truncated @click="openMapDialog">
        {{ displayText }}
      </el-text>
    </el-tooltip>

    <!-- 地图弹窗 -->
    <el-dialog
      v-model="dialogVisible"
      title="位置详情"
      width="60%"
      height="80%"
      @closed="destroyMap"
      :append-to-body="true"
      teleported
    >
      <div class="map-container">
        <div v-if="loading" class="map-loading">地图加载中...</div>
        <div ref="mapContainer" class="map-wrapper"></div>

        <el-descriptions :column="1" border class="mt-4">
          <el-descriptions-item label="地址">{{
            modelValue.address
          }}</el-descriptions-item>
          <el-descriptions-item label="经度">{{
            modelValue.lng
          }}</el-descriptions-item>
          <el-descriptions-item label="纬度">{{
            modelValue.lat
          }}</el-descriptions-item>
        </el-descriptions>

        <div class="dialog-footer mt-4">
          <el-button type="primary" @click="dialogVisible = false"
            >确定</el-button
          >
        </div>
      </div>
    </el-dialog>
  </div>
</template>

<script setup>
/**
 * 腾讯地址展示组件
 * 经纬度格式: GCJ02
 * @param {Object} modelValue - 绑定的坐标对象
 * @param {number} modelValue.lng - 经度
 * @param {number} modelValue.lat - 纬度
 * @param {string} modelValue.address - 地址
 */
import { ref, computed, watch, nextTick, markRaw } from 'vue';
import { ElMessage } from 'element-plus';

const props = defineProps({
  modelValue: {
    type: Object,
    default: () => ({
      address: '',
      lng: null,
      lat: null,
    }),
  },
});

// 腾讯地图配置
const mapKey = import.meta.env.VITE_APP_MAP_TMAP_AK; // 腾讯地图密钥
const mapInstance = ref(null);
const markerLayer = ref(null);

// 响应式状态
const dialogVisible = ref(false);
const loading = ref(false);
const mapContainer = ref(null);

// 显示控制
const displayText = computed(
  () => (props.modelValue && props.modelValue.address) || '暂无地址信息',
);

const showTooltip = computed(
  () =>
    props.modelValue &&
    props.modelValue.address &&
    props.modelValue.address.length > 20,
);

// 动态加载地图API
const loadTMap = () => {
  return new Promise((resolve) => {
    if (window.TMap) return resolve();

    const script = document.createElement('script');
    script.src = `https://map.qq.com/api/gljs?v=2.exp&key=${mapKey}&libraries=service&callback=init`;
    script.onload = resolve;
    document.head.appendChild(script);
  });
};

// 初始化地图
const initMap = async () => {
  try {
    loading.value = true;

    const [lng, lat] = [props.modelValue.lng, props.modelValue.lat];

    // 创建地图实例
    mapInstance.value = markRaw(
      new TMap.Map(mapContainer.value, {
        center: new TMap.LatLng(lat, lng),
        zoom: 16,
        pitch: 0,
        rotation: 0,
      }),
    );

    // 添加标记图层
    markerLayer.value = new TMap.MultiMarker({
      map: mapInstance.value,
      geometries: [
        {
          position: new TMap.LatLng(lat, lng),
          styleId: 'markerStyle',
        },
      ],
      styles: {
        markerStyle: new TMap.MarkerStyle({
          width: 32,
          height: 32,
          anchor: { x: 16, y: 32 },
        }),
      },
    });
  } catch (error) {
    ElMessage.error('地图初始化失败');
  } finally {
    loading.value = false;
  }
};

// 打开弹窗
const openMapDialog = async () => {
  if (!validateCoordinates()) return;

  dialogVisible.value = true;
  nextTick(async () => {
    if (!window.TMap) {
      await loadTMap();
    }
    if (!mapInstance.value) {
      await initMap();
    }
  });
};

// 坐标验证
const validateCoordinates = () => {
  const { lng, lat } = props.modelValue;
  if (!lng || !lat) {
    ElMessage.warning('坐标信息不完整');
    return false;
  }
  if (Math.abs(lng) > 180 || Math.abs(lat) > 90) {
    ElMessage.warning('无效的坐标范围');
    return false;
  }
  return true;
};

// 销毁地图
const destroyMap = () => {
  if (mapInstance.value) {
    mapInstance.value.destroy();
    mapInstance.value = null;
  }
};

// 监听坐标变化
watch(
  () => props.modelValue,
  (newVal) => {
    if (mapInstance.value && validateCoordinates()) {
      const [lng, lat] = [newVal.lng, newVal.lat];
      mapInstance.value.setCenter(new TMap.LatLng(lat, lng));
      markerLayer.value.setGeometries([
        {
          position: new TMap.LatLng(lat, lng),
        },
      ]);
    }
  },
);
</script>

<style scoped>
.tmap-address-display {
  cursor: pointer;
  display: inline-block;
  max-width: 400px;
}

.address-text {
  color: var(--el-color-primary);
  transition: color 0.3s;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.address-text:hover {
  color: var(--el-color-primary-light-3);
  text-decoration: underline;
}

.map-container {
  position: relative;
  height: 60vh;
}

.map-wrapper {
  height: 400px;
  width: 100%;
  border-radius: 4px;
  overflow: hidden;
}

.map-loading {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}

.dialog-footer {
  text-align: right;
}
</style>
